<template>
  <el-dialog 
    v-model="showDialog" 
    :title="title" 
    width="500px"
    :before-close="handleClose"
  >
    <el-form 
      ref="formRef" 
      :model="formData" 
      :rules="rules" 
      label-width="80px"
    >
      <el-form-item label="用户名" prop="username">
        <el-input 
          v-model="formData.username" 
          placeholder="请输入用户名" 
          clearable 
        />
      </el-form-item>
      <el-form-item label="真实姓名" prop="realname">
        <el-input 
          v-model="formData.realname" 
          placeholder="请输入真实姓名" 
          clearable 
        />
      </el-form-item>
      <el-form-item label="邮箱" prop="email">
        <el-input 
          v-model="formData.email" 
          placeholder="请输入邮箱" 
          clearable 
        />
      </el-form-item>
      <el-form-item label="手机号">
        <el-input 
          v-model="formData.phone" 
          placeholder="请输入手机号" 
          clearable 
        />
      </el-form-item>
      <el-form-item label="状态">
        <el-switch
          v-model="formData.status"
          :active-value="1"
          :inactive-value="0"
          active-text="启用"
          inactive-text="禁用"
        />
      </el-form-item>
    </el-form>
    
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleSubmit">确定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { ElMessage } from 'element-plus'
import { ref, watch, computed } from 'vue'

//接收父组件传入的值
const props = defineProps({
  //是否显示
  visible: {
    type: Boolean,
    required: true
  },
  //表单标题
  title: {
    type: String,
    default: '表单'
  },
  //表单信息
  formData: {
    type: Object,
    required: true
  },
  //表单验证规则
  rules: {
    type: Object,
    default: () => ({})
  }
});
//props是只读的，不能直接修改,v-model尝试直接修改prop的值，这是不允许的
//子组件中使用计算属性处理v-model来处理对话框的显示/隐藏状态
const showDialog = computed({
  get: () => props.visible,
  //子组件通过emit('update:visible', value)通知父组件更新状态
  //父组件使用:visible="dialogVisible" @update:visible="dialogVisible = $event"进行双向绑定
  set: (value) => emit('update:visible', value)
});
//传递visible值和调用父组件的submit和cancel事件
const emit = defineEmits(['update:visible', 'submit', 'cancel']);
//初始化formRef
const formRef = ref(null);

// 监听visible变化
watch(() => props.visible, (newVal) => {
  if (!newVal && formRef.value) {
    formRef.value.clearValidate()
  }
})
//关闭之前传递visible属性为false给父组件
const handleClose = () => {
  emit('update:visible', false)
}
//调用父组件的cancel方法,且传递visible的false属性
const handleCancel = () => {
  emit('cancel')
  emit('update:visible', false)
}
//提交表单信息
const handleSubmit = async () => {
  if (!formRef.value) return;
  
  try {
    const valid = await formRef.value.validate()
    if (valid) {
      emit('submit', props.formData);//调用父组件的提交方法并且把子组件内的信息传递给父组件
      emit('update:visible', false);//传递visible的false属性
    }
  } catch (error) {
    ElMessage.error('请正确填写表单！');
  }
}
</script>

<style scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>